package controller;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.ejb.EJBContext;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import util.Converter;
import model.ElementoBase;
import model.Escursione;
import model.Hotel;
import model.PacchettoPersonale;
import model.PacchettoPredefinito;
import model.Utente;
import model.Volo;
import dto.*;

/**
 * Session Bean implementation class Amministrazione
 */
@Stateless
public class Amministrazione implements AmministrazioneInterface {

    /**
     * Default constructor. 
     */
	@PersistenceContext
    private EntityManager em;
	@Resource
	private EJBContext context;
	
	
	@Override
	public void creaPacchetto() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void modificaPacchetto(PacchettoPredefinitoDTO pack) {
		em.merge(new PacchettoPredefinito(pack));
		
	}

	@Override
	public void eliminaPacchetto(PacchettoPredefinitoDTO pack) {
		PacchettoPredefinito remove = em.merge(new PacchettoPredefinito(pack));
		em.remove(remove);
		
	}

	@Override
	public void creaElementoBase(ElementoBaseDTO element) {
		ElementoBase newElemento = new ElementoBase(element);
		em.persist(newElemento);
	}

	@Override
	public ArrayList<String> modificaElementoBase(ElementoBaseDTO element) {

		em.merge(new ElementoBase(element));
		ArrayList<String> email = new ArrayList<String>();
		List<Utente> el= (List<Utente>) em.createQuery(
		        "SELECT u FROM Utente u Join Fetch u.pacchettiPersonali p Join Fetch p.elementi e"
		        + " where e.idElementoBase="+element.getIdElementoBase())
		        .getResultList();
		for(Utente e: el){
			email.add(e.getEmail());
		}
		return email;
	}

	@Override
	public ArrayList<String> eliminaElementoBase(ElementoBaseDTO element) {
		ArrayList<String> email = new ArrayList<String>();
		
		List<Utente> el= (List<Utente>) em.createQuery(
		        "SELECT u FROM Utente u Join Fetch u.pacchettiPersonali p Join Fetch p.elementi e"
		        + " where e.idElementoBase="+element.getIdElementoBase())
		        .getResultList();


		for(Utente e: el){
			System.out.println("Utente: "+e.getEmail());
			email.add(e.getEmail());
			
			List<PacchettoPersonale> pp = e.getPacchettiPersonali();
			for(PacchettoPersonale p : pp){
				List<ElementoBase> eb = p.getElementi();
				List<ElementoBase> newList = new ArrayList<ElementoBase>();
				for(ElementoBase ele : eb){
					if(ele.getIdElementoBase()!=element.getIdElementoBase()){
						newList.add(ele);

						
					}
					else{
						p.setTotale(p.getTotale()-ele.getPrezzo());
						System.out.println("Cancello "+ele.getNome());
					}
						
				}
				p.setElementi(newList);
				em.merge(p);
				
			}
			
			

		}
		
		List<Utente> el1= (List<Utente>) em.createQuery(
		        "SELECT u FROM Utente u Join Fetch u.giftList g"
		        + " where g.idElementoBase="+element.getIdElementoBase())
		        .getResultList();
		
		for(Utente e: el1){
			System.out.println("Utente: "+e.getEmail());
			email.add(e.getEmail());
			List<ElementoBase> gift = e.getGiftList();
			List<ElementoBase> newList = new ArrayList<ElementoBase>();
			for(ElementoBase ele : gift){
				if(ele.getIdElementoBase()!=element.getIdElementoBase()){
					newList.add(ele);					
				}				
				else
					System.out.println("Cancello "+element);
			}
			e.setGiftList(newList);
			em.merge(e);
			

		}
		
		
		List<Utente> el2= (List<Utente>) em.createQuery(
		        "SELECT u FROM Utente u Join Fetch u.pacchettiPredefiniti p Join Fetch p.elementi e"
		        + " where e.idElementoBase="+element.getIdElementoBase())
		        .getResultList();
		for(Utente e: el2){
			
			List<PacchettoPredefinito> pp = e.getPacchettiPredefiniti();
			for(PacchettoPredefinito p : pp){
				List<ElementoBase> eb = p.getElementi();
				List<ElementoBase> newList = new ArrayList<ElementoBase>();
				for(ElementoBase ele : eb){
					if(ele.getIdElementoBase()!=element.getIdElementoBase()){
						newList.add(ele);						
					}
					else{
						p.setTotale(p.getTotale()-ele.getPrezzo());
						p.setApprovato(false);
						System.out.println("Cancello "+ele.getNome());
					}
						
				}
				p.setElementi(newList);
				em.merge(p);
				
			}
			
			

		}
		
		ElementoBase remove = em.merge(new ElementoBase(element));
		em.remove(remove);
		return email;
	}

	@Override
	public void creaVolo(ElementoBaseDTO element, VoloDTO volo) {
		/*
		ElementoBase newElemento = new ElementoBase(element);
		em.persist(newElemento);
		em.flush();
		volo.setIdElementoBase(newElemento.getIdElementoBase());
		volo.setElemento(element);
		em.persist(new Volo(volo));
		*/
		ElementoBase newElemento = new ElementoBase(element);
		em.persist(newElemento);
		em.flush();
		element.setIdElementoBase(newElemento.getIdElementoBase());
		volo.setElemento(element);
		volo.setIdElementoBase(newElemento.getIdElementoBase());
		em.persist(new Volo(volo));	
		
	}

	@Override
	public void creaHotel(ElementoBaseDTO element, HotelDTO hotel) {
		ElementoBase newElemento = new ElementoBase(element);
		em.persist(newElemento);
		em.flush();
		element.setIdElementoBase(newElemento.getIdElementoBase());
		hotel.setElemento(element);
		hotel.setIdElementoBase(newElemento.getIdElementoBase());
		em.persist(new Hotel(hotel));	
		/*
		ElementoBase newElemento = new ElementoBase(element);
		em.persist(newElemento);
		em.flush();
		hotel.setIdElementoBase(newElemento.getIdElementoBase());
		hotel.setElemento(element);
		em.persist(new Hotel(hotel));
		*/
	}
	
	

	@Override
	public void creaEscursione(ElementoBaseDTO element, EscursioneDTO esc) {		
		ElementoBase newElemento = new ElementoBase(element);
		em.persist(newElemento);
		em.flush();
		element.setIdElementoBase(newElemento.getIdElementoBase());
		esc.setElemento(element);
		esc.setIdElementoBase(newElemento.getIdElementoBase());
		em.persist(new Escursione(esc));		
	}

	@Override
	public PacchettoPredefinitoDTO getPacchettoPredefinitoPK(int id) {

		PacchettoPredefinito p = em.find(PacchettoPredefinito.class, id);
		if(p!=null)
		return Converter.convertToDTO(p);
		else return null;

	}
	
	private void check(int id){
		List<Utente> el2= (List<Utente>) em.createQuery(
		        "SELECT u FROM Utente u Join Fetch u.pacchettiPredefiniti p Join Fetch p.elementi e"
		        + " where e.idElementoBase="+id)
		        .getResultList();
		
		for(Utente e: el2){
			List<PacchettoPredefinito> pp = e.getPacchettiPredefiniti();
			for(PacchettoPredefinito p : pp){
				List<ElementoBase> eb = p.getElementi();
				for(ElementoBase ele : eb){
					if(ele.getIdElementoBase()==id){
						p.setApprovato(false);
					}
						
				}
				em.merge(p);
				
			}
	}
	}

	@Override
	public ArrayList<String> modificaVolo(VoloDTO volo) {
		check(volo.getIdElementoBase());
		em.merge(new Volo(volo));
		ArrayList<String> email = new ArrayList<String>();
		List<Utente> el= (List<Utente>) em.createQuery(
		        "SELECT u FROM Utente u Join Fetch u.pacchettiPersonali p Join Fetch p.elementi e"
		        + " where e.idElementoBase="+volo.getIdElementoBase())
		        .getResultList();
		for(Utente e: el){
			email.add(e.getEmail());
		}
		return email;
	}

	@Override
	public ArrayList<String> modificaEscursione(EscursioneDTO escursione) {
		check(escursione.getIdElementoBase());
		em.merge(new Escursione(escursione));
		ArrayList<String> email = new ArrayList<String>();
		List<Utente> el= (List<Utente>) em.createQuery(
		        "SELECT u FROM Utente u Join Fetch u.pacchettiPersonali p Join Fetch p.elementi e"
		        + " where e.idElementoBase="+escursione.getIdElementoBase())
		        .getResultList();
		for(Utente e: el){
			email.add(e.getEmail());
		}
		return email;
	}

	@Override
	public ArrayList<String> modificaHotel(HotelDTO hotel) {
		check(hotel.getIdElementoBase());
		em.merge(new Hotel(hotel));
		ArrayList<String> email = new ArrayList<String>();
		List<Utente> el= (List<Utente>) em.createQuery(
		        "SELECT u FROM Utente u Join Fetch u.pacchettiPersonali p Join Fetch p.elementi e"
		        + " where e.idElementoBase="+hotel.getIdElementoBase())
		        .getResultList();
		for(Utente e: el){
			email.add(e.getEmail());
		}
		return email;
	}


	
	

}
